package part20;

import part20.annotation.Constraints;
import part20.annotation.DBTable;
import part20.annotation.SQLInteger;
import part20.annotation.SQLString;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * @author wcj
 * @Date 2021/6/6 16:25
 * @Version 1.0
 */
public class Part204 {

    public static void main(String[] args) {
        System.out.println(getDbCommand(new Class[]{Part203.class, User.class}));
    }

    /**
     * 数据库建表语句生成的注解处理器
     *
     * @param types
     */
    public static List<String> getDbCommand(Class<?>[] types) {
        if (types.length < 1) {
            throw new RuntimeException("No Class need create table!");
        }

        List<String> sqlList = new ArrayList<>();
        for (Class<?> type : types) {
            StringBuilder sb = new StringBuilder("CREATE TABLE ");
            // 表名的获取
            Annotation[] classAnnotations = type.getAnnotations();
            for (Annotation classAnnotation : classAnnotations) {
                if (classAnnotation instanceof DBTable) {
                    String tableName = ((DBTable) classAnnotation).name();
                    if (tableName.length() < 1) {
                        tableName = type.getTypeName().toUpperCase();
                    }
                    sb.append(tableName + "(");
                }
            }

            // 获取表的字段信息
            Field[] declaredFields = type.getDeclaredFields();
            for (Field field : declaredFields) {
                Annotation[] annotations = field.getAnnotations();
                for (Annotation annotation : annotations) {
                    if (annotation instanceof SQLInteger) {
                        String columnName = ((SQLInteger) annotation).name();
                        if (columnName.length() < 1) {
                            columnName = field.getName();
                        }
                        Constraints constraints = ((SQLInteger) annotation).constraints();
                        sb.append(columnName + " INT " + getConstraints(constraints) + ",");
                    }

                    if (annotation instanceof SQLString) {
                        String columnName = ((SQLString) annotation).name();
                        if (columnName.length() < 1) {
                            columnName = field.getName();
                        }
                        Constraints constraints = ((SQLString) annotation).constraints();
                        sb.append(columnName + " VARCHAR(" + ((SQLString) annotation).value() + ") " + getConstraints(constraints) + ",");
                    }
                }
            }
            sqlList.add(sb.toString().substring(0, sb.toString().lastIndexOf(",")) + ")");
        }
        return sqlList;
    }

    public static String getConstraints(Constraints con) {
        String constraints = "";
        if (con.allowNull()) {
            constraints += "NOT NULL ";
        }
        if (con.primaryKey()) {
            constraints += "PRIMARY KEY ";
        }
        if (con.unique()) {
            constraints += "UNIQUE ";
        }
        return constraints;
    }
}

@DBTable
class User {

    @SQLInteger
    int id;

    @SQLString(value = 20)
    String username;

    @SQLString(value = 64)
    String password;
}
